Skip to content

feat: rework clip catalog (group paste, folder metadata, panel polish)#215

Merged
fuzzzerd merged 6 commits into
masterfrom
fuzzz/group-paste-folder-hierarchy
May 19, 2026
Merged

feat: rework clip catalog (group paste, folder metadata, panel polish)#215
fuzzzerd merged 6 commits into
masterfrom
fuzzz/group-paste-folder-hierarchy

Conversation

@fuzzzerd
Copy link
Copy Markdown
Owner

@fuzzzerd fuzzzerd commented May 19, 2026

Summary

Pasting a script Group from FileMaker decomposes into one clip per <Script>, mirroring the Group hierarchy as folders in the clip repository. Single-clip paste behavior is unchanged.

  • GroupPasteDecomposer walks fmxmlsnippet, emitting one entry per <Script> plus a FolderData per <Group> carrying id, includeInMenu, and groupCollapsed. Returns null when the snippet has no Group so the existing single-clip path is preserved.
  • MainWindowViewModel.PasteFileMakerClipData branches on the decomposer's result and lands group pastes relative to the currently selected clip/folder, so the paste appears where the user was looking. Loose scripts alongside a Group share the paste root; nested Groups produce nested folders.
  • Name uniqueness is scoped per-folder, so two clips with the same name in different folders are allowed; collisions suffix (2), (3), …
  • Folder-name collisions merge into the existing folder.

Folder persistence

  • New FolderData model carries Group metadata; IClipRepository gains default-implemented LoadFoldersAsync / SaveFoldersAsync.
  • ClipRepository persists folders as .sharpfm-folder.json sidecars; empty folders survive saves and load as standalone tree nodes.
  • New Folder command added (File menu + tree context menu); the tree tracks folder selection so new clips, folders, and pastes land in the targeted folder.
  • Invalid filename characters are percent-encoded on disk for both clip names and folder segments.

Tree UX

  • Tree pre-expands by default and rebinds TreeViewItem.IsExpanded so expansion state survives rebuilds.
  • Explicit root node added; clip panel fills available height.
  • File menu splits "New Script" (Mac-XMSC) vs "New Script Steps" (Mac-XMSS).

Tests

Coverage spans the decomposer (single Group, multiple scripts, nested Groups, loose scripts, attribute capture), the paste handler (group + collision + paste-at-selected-hierarchy), folder persistence + percent-encoding round-trips, and tree-selection behavior. Full suite: 1306 + 101 passing.

Closes #206

Pastes whose root contains <Group> elements now expand into one clip
per <Script>, mirroring the Group hierarchy as FolderPath segments.
Loose scripts paste at the currently selected clip's folder; Groups
nest beneath it. Folder name collisions merge into the existing folder.
@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 19, 2026

Test Results

✔️ Tests 1407 / 1407 - passed in 17.6s
✔️ Coverage 79.18% - passed with 70% threshold
📏 15140 / 17588 lines covered 🌿 5129 / 8010 branches covered
🔍 click here for more details

✏️ updated for commit 46f1fab

fuzzzerd added 5 commits May 18, 2026 21:54
- Add FolderData with FileMaker Group attributes (id, includeInMenu, groupCollapsed)
- Extend IClipRepository with LoadFoldersAsync/SaveFoldersAsync (default-implemented)
- Persist folders as .sharpfm-folder.json sidecars; empty folders survive saves
- Capture Group attributes when decomposing a paste; carry forward through the host
- Track folder selection in the tree so new clip/folder/paste land in the targeted folder
- Add New Folder command to the File menu and tree context menu
Names containing '/', ':', or other reserved characters now round-trip cleanly
through the local file-system repository instead of failing the save with a
DirectoryNotFoundException or losing folder segments to sanitization.
- Tree context menu mirrors the File/Edit commands so New / Paste / Copy /
  Rename / Delete work consistently regardless of how the menu was opened
- New Script creates a whole-script clip (Mac-XMSC); New Script Steps creates
  a bare step list (Mac-XMSS), matching the existing Copy-as-... split
- Tapping a folder leaves the active editor tab alone; right-clicking empty
  tree area targets the repository root
- New Folder no longer auto-selects the just-created folder, so successive
  invocations produce siblings instead of nesting
The clip tree now fills the entire left panel via DockPanel layout so empty
space below the last node is a valid right-click target for root operations.
A single synthetic root node (labeled after the repo's leaf folder) wraps
the top-level items, giving root-targeted actions an explicit click target
regardless of how much content fills the panel.
The clip tree's IsExpanded property on the VM was never wired to the
container, so every RebuildTree triggered by a new clip, paste, or folder
operation collapsed the tree back to Avalonia's default. A two-way style
setter on TreeViewItem.IsExpanded honours the VM (default true) and routes
chevron clicks back to it.
@fuzzzerd fuzzzerd changed the title feat: decompose pasted script Groups into folder hierarchy feat: rework clip catalog (group paste, folder metadata, panel polish) May 19, 2026
@fuzzzerd fuzzzerd merged commit 333ff5a into master May 19, 2026
6 checks passed
@fuzzzerd fuzzzerd deleted the fuzzz/group-paste-folder-hierarchy branch May 19, 2026 23:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Paste Group: mirror script-folder hierarchy from FileMaker into the clip repository

1 participant